package hypeerweb;

import java.sql.*;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class HyPeerWeb {

	private Node web;
	private HyPeerWebDatabase database;

	private static HyPeerWeb singleton;

	private HyPeerWeb() {
		// can add a comparator as a parameter to sort the nodes
		web = null;

		reload();
	}

	public static HyPeerWeb getSingleton() {
		if (singleton == null) {
			singleton = new HyPeerWeb();
		}

		return singleton;
	}

	public int size() {

		int i = 0;
		Node node = getNode(i);
		while (node != null) {
			i++;
			node = getNode(i);
		}
		// iterate from 0 to NULL_NODE to find number of nodes
		return i;
	}

	public Node getNode(int i) {
		if (web == null) {
			return null;
		}
		return findNearestNode(web, i);
	}

	public Node findNearestNode(Node n, int target) {

		if (n.getId() == target) {
			return n;
		}

		else {
			List<Node> neighbors;
			neighbors = n.getNeighbors();
			for (int i = neighbors.size() - 1; i >= 0; i--) {
				int id = neighbors.get(i).getId();

				if (n.getId() > target) {

					if (id <= target && id < n.getId()) {
						return findNearestNode(neighbors.get(i), target);
					}
				} else if (id <= target && id > n.getId()) {
					return findNearestNode(neighbors.get(i), target);
				}
			}
		}

		return null;

	}

	public boolean contains(Node node) {
		Node other = getNode(node.getId());
		return (node.compareTo(other) == 0) ? true : false;
	}

	public void clear() {
		web = null;
	}

	public void addNode(Node node) {
		addToHyPeerWeb(node, null);
	}

	public void removeNode(Node node) {
		removeFromHypeerweb(node,null);
	}
 
  public void removeFromHypeerweb(Node nodeToRemove, Node startNode) {
   
  }

	public void reload() {
		reload("");
	}

	public void reload(java.lang.String dbName) {
		clear();

		HyPeerWebDatabase.initHyPeerWebDatabase(dbName);
		database = HyPeerWebDatabase.getSingleton();

		// web.addAll(database.getNodes());

		TreeSet<Node> nodes = new TreeSet<Node>(database.getNodes());

		if (!nodes.isEmpty()) {
			web = nodes.first();
		} else {
			web = null;
		}
	}

	public HyPeerWebDatabase getHyPeerWebDatabase() {
		return database;
	}

	public void saveToDatabase() {

		int i = 0;
		Node node = getNode(i);

		while (node != null) {
			i++;
			try {
				database.storeNode(node);
			} catch (SQLException e) {
				System.out.println(e.getStackTrace());
			}
			node = getNode(i);
		}
	}

	public void addToHyPeerWeb(Node newNode, Node startNode) {

		if (startNode == null) {
			if (web == null) {
				web = newNode;
			} else {
				web.addToHyPeerWeb(newNode);
			}
		} else {
			startNode.addToHyPeerWeb(newNode);
		}
	}
}
